package io.adminboot.service.impl;

import io.adminboot.domain.vo.PageVO;
import io.adminboot.entity.SysUser;
import io.adminboot.entity.SysUserExample;
import io.adminboot.exception.MyException;
import io.adminboot.repository.extend.SysUserExtMapper;
import io.adminboot.service.SysRoleService;
import io.adminboot.service.SysUserRoleService;
import io.adminboot.service.SysUserService;
import io.adminboot.utils.Constant;
import org.apache.commons.lang.RandomStringUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.crypto.hash.Sha256Hash;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.Arrays;
import java.util.Date;
import java.util.List;

/**
 * 系统用户
 * 
 */
@Service("sysUserService")
public class SysUserServiceImpl implements SysUserService {
	
	@Autowired
	private SysUserExtMapper mapper;
	@Autowired
	private SysUserRoleService sysUserRoleService;
	@Autowired
	private SysRoleService sysRoleService;

	@Override
	public PageVO queryPage(Integer pageNum, Integer pageSize, String username, Long createUserId) {
		List<SysUser> list = mapper.selectList((pageNum - 1) * pageSize, pageSize, createUserId, username);
		int totalCount = mapper.count(createUserId, username);
		PageVO page = new PageVO(list, totalCount, pageSize, pageNum);
		return page;
	}

	@Override
	public List<String> queryAllPerms(Long userId) {
		return mapper.selectAllPerms(userId);
	}

	@Override
	public List<Long> queryAllMenuId(Long userId) {
		return mapper.selectAllMenuId(userId);
	}

	@Override
	public SysUser queryByUserName(String username) {
		SysUserExample example = new SysUserExample();
		example.createCriteria().andUsernameEqualTo(username);
		List<SysUser> list = mapper.selectByExample(example);
		return CollectionUtils.isEmpty(list) ? null : list.get(0);
	}

	@Override
	@Transactional
	public void save(SysUser user) {
		user.setCreateTime(new Date());
		//sha256加密
		String salt = RandomStringUtils.randomAlphanumeric(20);
		user.setPassword(new Sha256Hash(user.getPassword(), salt).toHex());
		user.setSalt(salt);
		mapper.insert(user);
		
		//检查角色是否越权
		checkRole(user);
		
		//保存用户与角色关系
		sysUserRoleService.saveOrUpdate(user.getId(), user.getRoleIdList());
	}

	@Override
	@Transactional
	public void update(SysUser user) {
		if(StringUtils.isBlank(user.getPassword())){
			user.setPassword(null);
		}else{
			user.setPassword(new Sha256Hash(user.getPassword(), user.getSalt()).toHex());
		}
		mapper.updateByPrimaryKey(user);
		
		//检查角色是否越权
		checkRole(user);
		
		//保存用户与角色关系
		sysUserRoleService.saveOrUpdate(user.getId(), user.getRoleIdList());
	}

	@Override
	public void deleteBatch(Long[] userId) {
		mapper.batchDelete(Arrays.asList(userId));
	}

	@Override
	public boolean updatePassword(Long userId, String password, String newPassword) {
		SysUser userEntity = mapper.selectByPrimaryKey(userId);
		userEntity.setPassword(newPassword);
		
		int result = mapper.updateByPrimaryKey(userEntity);
		return result > 0;
	}
	
	/**
	 * 检查角色是否越权
	 */
	private void checkRole(SysUser user){
		if(user.getRoleIdList() == null || user.getRoleIdList().size() == 0){
			return;
		}
		//如果不是超级管理员，则需要判断用户的角色是否自己创建
		if(user.getCreateUserId() == Constant.SUPER_ADMIN){
			return ;
		}
		
		//查询用户创建的角色列表
		List<Long> roleIdList = sysRoleService.queryRoleIdList(user.getCreateUserId());

		//判断是否越权
		if(!roleIdList.containsAll(user.getRoleIdList())){
			throw new MyException("新增用户所选角色，不是本人创建");
		}
	}

	@Override
	public SysUser queryById(Long userId) {
		return mapper.selectByPrimaryKey(userId);
	}
}
